﻿using System;
using System.Collections.Generic;
using System.Linq;
using AcademicPlanner.Data;
using AcademicPlanner.Data.Entities;
using AcademicPlanner.Data.Repositories;

namespace AcademicPlanner.Domain.Models.Collections
{
	/// <summary>
	/// PersonCollection represents a collection of <c>Person</c>s.
	/// </summary>
	/// <version>1.0</version>
	/// <since>1.0</since>
	public class PersonCollection : ModelCollection<Person, PersonEntityRepository, PersonEntity>
	{
		/// <summary>
		/// Gets the data layer repository of the underlying <c>PersonEntity</c>s of this collection's <c>Person</c>s.
		/// </summary>
		/// <version>1.0</version>
		/// <since>1.0</since>
		protected override PersonEntityRepository EntityRepo { get { return DomainMaster.DSAS.PersonEntityRepo; } }


		/// <summary>
		/// No argument constructor; invokes the matching base class constructor.
		/// </summary>
		/// <seealso cref="M:AcademicPlanner.Domain.ModelCollection<TModel, TEntityRepo, TREntity>.ModelCollection"/>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public PersonCollection() : base()
		{

		}


		/// <summary>
		/// Filters this PersonCollection to return only the <c>Person</c> with the given
		/// email address. This method relies on this PersonCollection's 
		/// <see cref="P:EntityRepo"/> to find the matching <c>PersonEntity</c> then creates
		/// the <c>Person</c> represented by that <c>PersonEntity</c>.
		/// </summary>
		/// <param name="pEmail">The email address.</param>
		/// <returns>The <c>Person</c> having the given email or <c>null</c>.</returns>
		/// <exception cref="T:AcademicPlanner.Domain.CriticalDomainException">
		/// Thrown with an error code of <c>DomainErrorCode.M_PERSON_ENTITY_RETRIEVAL_BY_EMAIL_FAILURE</c>
		/// when a <see cref="T:AcademicPlanner.Data.DataException"/> occurs;
		/// the <see cref="T:AcademicPlanner.Data.DataException"/> is accessible through the
		/// <c>InnerException</c> property.
		/// </exception>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.ModelsFountain"/>
		/// <seealso cref="M:AcademicPlanner.Domain.ModelsFountain.GetPerson"/>
		/// <seealso cref="P:EntityRepo"/>
		/// <seealso cref="M:AcademicPlanner.Data.PersonEntityRepository.FindByEmail"/>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public Person WithEmail(string pEmail)
		{
			Person rPers = null;
			PersonEntity vEnt = null;

			try
			{
				vEnt = EntityRepo.FindByEmail(pEmail);
			}
			catch (DataException vDx)
			{
				var vCx = new CriticalDomainException(DomainErrorCode.M_PERSON_ENTITY_RETRIEVAL_BY_EMAIL_FAILURE, vDx);
				throw vCx;
			}

			if (vEnt != null)
				rPers = DomainMaster.ModelsFountain.GetPerson(vEnt);

			return rPers;
		}
	}
}
